package com.tiantian.user.listener;

import cn.dev33.satoken.secure.BCrypt;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.tiantian.common.core.constant.RoleConstants;
import com.tiantian.common.core.utils.SpringUtils;
import com.tiantian.common.core.utils.ValidatorUtils;
import com.tiantian.common.excel.core.ExcelListener;
import com.tiantian.common.excel.core.ExcelResult;
import com.tiantian.common.satoken.utils.LoginHelper;
import com.tiantian.user.domain.entity.SysUser;
import com.tiantian.user.domain.vo.ImportUserErrorMsg;
import com.tiantian.user.domain.vo.SysUserImportVo;
import com.tiantian.user.service.SysUserService;
import lombok.extern.slf4j.Slf4j;
import net.sourceforge.pinyin4j.PinyinHelper;
import net.sourceforge.pinyin4j.format.HanyuPinyinCaseType;
import net.sourceforge.pinyin4j.format.HanyuPinyinOutputFormat;
import net.sourceforge.pinyin4j.format.HanyuPinyinToneType;
import net.sourceforge.pinyin4j.format.exception.BadHanyuPinyinOutputFormatCombination;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

/**
 * 系统用户自定义导入
 *
 * @author Lion Li
 */
@Slf4j
public class SysUserImportListener extends AnalysisEventListener<SysUserImportVo> implements ExcelListener<SysUserImportVo> {

    private final SysUserService userService;
    private final String operUserName;

    private int failureNum = 0;
    private int curNumber = 0;

    private final List<SysUserImportVo> list = new ArrayList<>();
    private final List<ImportUserErrorMsg> errorList = new ArrayList<>();

    public SysUserImportListener() {
        this.userService = SpringUtils.getBean(SysUserService.class);
        this.operUserName = LoginHelper.getNickName();
    }

    @Override
    public void invoke(SysUserImportVo userVo, AnalysisContext context) {
        boolean isUnique = this.userService.checkStudentIdUnique(userVo.getStudentId());
        curNumber++;
        try {
            // 验证是否存在这个用户
            if (isUnique) {
                ValidatorUtils.validate(userVo);
                SysUser sysUser = new SysUser();
                // 基本属性
                sysUser.setUserType("01");
                sysUser.setNickName(userVo.getNickName());
                sysUser.setPhonenumber(userVo.getPhonenumber());
                sysUser.setEmail(userVo.getEmail());
                sysUser.setStudentId(userVo.getStudentId());
                sysUser.setClasz(userVo.getClasz());
                sysUser.setCreateTime(LocalDateTime.now());
                sysUser.setCreateBy(operUserName);
                sysUser.setAvatar("http://10.226.8.14:9000/jx-welcome-minio/default_avatar.png");
                // 设置账号(学号) 密码(学号后6位 + 姓名首字母小写)
                sysUser.setUserName(userVo.getStudentId());
                sysUser.setPassword(getInitPassword(sysUser));
                // 新增用户
                userService.registerUser(sysUser, RoleConstants.CANDIDATE);
                list.add(userVo);
            } else {
                failureNum++;
                // 用户已存在
                errorList.add(new ImportUserErrorMsg(userVo, curNumber, "用户已存在"));
            }
        } catch (Exception e) {
            e.printStackTrace();
            failureNum++;
            String errorMsg;
            if (e.getCause() != null) {
                errorMsg = e.getCause().getMessage();
            } else {
                errorMsg = e.getMessage();
            }
            errorList.add(new ImportUserErrorMsg(userVo, curNumber, errorMsg));
        }
    }

    /**
     * 获取初始化密码
     * 学号后6位 + 姓名首字母小写
     */
    public String getInitPassword(SysUser sysUser) {
        String studentId = sysUser.getStudentId();
        String nickName = sysUser.getNickName();
        String prefix = studentId.substring(studentId.length() - 6);
        String suffix = getFirstPinYin(nickName);
        return BCrypt.hashpw(prefix + suffix);
    }

    /**
     * 分别获取中文汉字的第一个首字母
     */
    public String getFirstPinYin(String hanyu) {
        HanyuPinyinOutputFormat format = new HanyuPinyinOutputFormat();
        format.setCaseType(HanyuPinyinCaseType.UPPERCASE);
        format.setToneType(HanyuPinyinToneType.WITHOUT_TONE);

        StringBuilder firstPinyin = new StringBuilder();
        char[] hanyuArr = hanyu.trim().toCharArray();
        try {
            for (char c : hanyuArr) {
                if (Character.toString(c).matches("[\\u4E00-\\u9FA5]+")) {
                    String[] pys = PinyinHelper.toHanyuPinyinStringArray(c, format);
                    firstPinyin.append(pys[0].charAt(0));
                } else {
                    firstPinyin.append(c);
                }
            }
        } catch (BadHanyuPinyinOutputFormatCombination badHanyuPinyinOutputFormatCombination) {
            badHanyuPinyinOutputFormatCombination.printStackTrace();
        }
        return firstPinyin.toString().toLowerCase();
    }

    public String getErrorString(SysUserImportVo userVo, String errorMessage) {
        return userVo.toString() + errorMessage;
    }

    @Override
    public void doAfterAllAnalysed(AnalysisContext context) {

    }

    @Override
    public ExcelResult<SysUserImportVo> getExcelResult() {
        return new ExcelResult<>() {

            @Override
            public String getAnalysis() {
                if (failureNum > 0) {
                    return "很抱歉，部分数据导入失败！共 " + failureNum + " 条数据格式不正确，错误如下：";
                }
                return "恭喜您，数据已全部导入成功！";
            }

            @Override
            public List<SysUserImportVo> getList() {
                return list;
            }

            @Override
            public List<ImportUserErrorMsg> getErrorList() {
                return errorList;
            }
        };
    }
}
